Dangeon Warder Panel
Вступительная часть
Всем доброго здравия, дорогие друзья!
Этим постом я начинаю серию публикаций о том, как я разрабатываю систему для ведения интерактивный НРИ. В тегах указана пятая редакция Подземелий, но на самом деле речь о любой НРИ. Привязки к конкретным правилам нет, подразумевается, что все необходимые действия (типа бросков кубиков) игроки будут совершать ручками за столом. А программа нужна только для визуализации перемещений, отображения карт и создания показательных боевых ситуаций. Ну и автоматическая выдача опыта, но это опционально и об этом потом.
И так, начнём с самых азов. На чём всё это безобразие будет работать?
На Unity. Почему? Да потому что на ней достаточно дёшево реализуется общение с ГПУ, а оно нам тут понадобится.
Полностью рассказывать о том, как и что я сделал смысла не вижу, но буду делиться какими интересными выкладками и, возможно, кусками кода, если они кому-то нужны.
Что мы сейчас имеем:
1. Система приключений
2. Внутри каждого приключения есть система игровых сессий
3. Внутри сессий и приключений есть возможность редактирования базы НИП, заданий, предметов и локаций
Кстати, UI в окне приключения реализован, как мне кажется, достаточно элегантно: он строится динамически, и в него легко буквально одной строчкой можно добавить новые разделы, которые сразу же отрисуются и кнопочкой и панелькой.
Для этого у меня создан класс SectionsManager, который висит в памяти приложения как Singleton. Он хранит в себе информацию о том, какие разделы мы будем использовать. Добавлять их туда можно через конфиги или через код, это уже вопрос того, кому как удобно.
А потом есть код, отвечающий чисто за UI и он ждёт от этого менеджера команду, когда тот всю необходимую информацию соберёт и скажет, что вот сейчас уже можно рисовать
private void Awake()
{
SectionsManager.GetInstance().IsReadyToRender += Render;
}
private void Render()
{
Sequence seq = DOTween.Sequence();
foreach (IMenuSection section in SectionsManager.GetInstance().Sections) {
SectionButton button = Instantiate(sectionButtonPrefab, transform);
RectTransform rt = button.GetComponent<RectTransform>();
CanvasGroup cg = button.GetComponent<CanvasGroup>();
cg.alpha = 0f;
button.transform.localScale = Vector3.zero;
button.Init(section.GetName(), () => { section.Show(transform.parent); });
seq.AppendCallback(() =>
{
cg.DOFade(1f, 0.3f).SetEase(Ease.OutQuad);
button.transform.DOScale(1f, 0.4f).SetEase(Ease.OutBack);
});
seq.AppendInterval(0.1f);
}
}
Конечно, каждую секцию нужно предварительно настроить и сохранить как префаб, совсем магии тут нет, но зато управление такими секциями становится максимально простым. Не захочет мастер пользоваться функционалом заданий, зачем ему занимать память приложения и заграмождать интерфейс ненужным функционалом. Он его отключит, приложение его выгрузит и забудет до тех пор, пока Мастер снова не захочет им воспользоваться.
Понятия не имею, интересно ли это вообще хоть кому-то, но я искренне надеюсь, что среди пользователей сайта есть люди неравнодушные к программированию, геймдеву и НРИ.
Посему жду комментариев, вопросов, критики, чего угодно.
Всем хороших игр!
Вот надо тебе сделать деталь конструкции. Возможно, одна должна уметь двигаться и выдерживать какие-т...